#ifndef XG_HTTPHELPER_CPP
#define XG_HTTPHELPER_CPP
//////////////////////////////////////////////////////////
#include "../HttpHelper.h"
#include "../../openssl/SSLSocket.h"

static thread_local int status = 0;

int HttpHelper::GetLastStatus()
{
	return status;
}
void HttpHelper::SetLastStatus(int code)
{
	status = code;
}
sp<Socket> HttpHelper::Connect(const string& ip, int port, bool crypted)
{
	return crypted ? SSLSocketPool::Connect(ip, port) : SocketPool::Connect(ip, port);
}
int HttpHelper::GetLinkSet(set<string>& uset, const string& html, const string& host)
{
	char tag = 0;
	string str = html;
	string hdr = "https";
	string key = stdx::trim(host, HTTP_SPACELIST);
	string taglist[] = {"https://", "http://", "href=", "src=", "url("};

	if (key.find(hdr) == 0)
	{
		hdr += ":";
	}
	else
	{
		hdr[4] = ':';
	}

	for (int i = 0; i < ARR_LEN(taglist); i++)
	{
		vector<string> vec = stdx::split(str, taglist[i]);

		for (size_t j = 1; j < vec.size(); j++)
		{
			string pre = vec[j - 1];
			string tmp = stdx::trim(vec[j]);

			if (tmp.empty()) continue;

			if (i <= 1)
			{
				tag = pre.empty() ? ' ' : pre.back();
				tmp = taglist[i] + tmp;
			}
			else if (i <= 3)
			{
				tag = tmp.front();
				tmp = tmp.substr(1);
			}
			else
			{
				tag = ')';
			}

			size_t pos = tmp.find(tag == '=' ? ' ' : tag);

			if (pos == string::npos || pos > 0xFF) continue;

			string url = stdx::trim(tmp.substr(0, pos), " /\\\r\n\t\'\"");

			if (key.length() > 0 && url.find("http") && url.find("www"))
			{
				if (url.front() == '/')
				{
					url = url[1] == '/' ? hdr + url : host + url;
				}
				else
				{
					url = key + "/" + url;
				}
			}

			uset.insert(url);
		}
	}

	return uset.size();
}
string HttpHelper::GetLink(const string& path, const string& host, int port, bool crypted)
{
	if (crypted)
	{
		if (port == 443)
		{
			return stdx::format("https://%s/%s", host.c_str(), path.c_str());
		}
		else
		{
			return stdx::format("https://%s:%d/%s", host.c_str(), port, path.c_str());
		}
	}
	else
	{
		if (port == 80)
		{
			return stdx::format("http://%s/%s", host.c_str(), path.c_str());
		}
		else
		{
			return stdx::format("http://%s:%d/%s", host.c_str(), port, path.c_str());
		}
	}
}
SmartBuffer HttpHelper::GetResultEx(const string& url, const string& data, const string& contype, const string& cookie, bool simplify)
{
	string link = url;

	for (int i = 0; i < 3; i++)
	{
		int port;
		string ip;
		string host;
		string path;
		bool crypted;
		HttpRequest request;

		if (!HttpRequest::GetInfoFromURL(link, host, path, ip, port, crypted))
		{
			status = XG_SENDFAIL;

            return SmartBuffer();
		}

		request.init(path, eUNKNOWN, simplify);

		if (data.length() > 0)
		{
			request.setMethod(ePOST);
			request.setPayload(data);
		}

		request.setHeadHost(host, port);

		if (contype.length() > 0) request.setContentType(contype);

		if (cookie.length() > 0) request.setHeadValue("Cookie", cookie);

        sp<Socket> sock = Connect(ip, port, crypted);

		if (!sock)
		{
			status = XG_SENDFAIL;

			return SmartBuffer();
		}

        sp<HttpResponse> response = request.getResponse(sock);

        if (!response)
        {
			status = XG_RECVFAIL;

            return SmartBuffer();
        }

		status = response->getErrorCode();

		if (status == 200) return response->getResult();

		link = response->getHeadValue("Location");

		if (link.empty())
		{
			link = response->getHeadValue("location");
				
			if (link.empty()) return response->getResult();
		}
	}

	status = XG_DATAERR;

	return SmartBuffer();
}
//////////////////////////////////////////////////////////
#endif